﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using Microsoft.Reporting.WinForms;
using System.Data;
using System.Configuration;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace card
{
   public class PrintCode
    {
        public  card.WebDG.Service ws = new card.WebDG.Service();
        public  void Run(string _ID, string _BT)
        {
            DateTime dtnow = DateTime.Now;
            ReportViewer report = new ReportViewer();

            string sql = "  SELECT DECODE((SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%'),NULL, TO_CHAR(SYSDATE,'YYMM')||'000001',(SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%')) AS BH " +
              " ,TRUCKNO AS CH,LOGINTIME AS DJSJ,COMMANDTIME AS ZLSJ,CARDTIME AS QRSJ,SHIPNAME||'/'||VOYAGE  AS CMHC "
              + ",BILL_NO  AS TDH,PIECES AS JS,CARGONAME AS HM,WEIGHT AS ZL,YARD AS DD,ZYJX AS JX, REMARK AS BZ "
              + " ,'" + Session.Operator_User + "' AS DZY,CARDADD AS TCC,'" + dtnow.ToString() + "' AS ZDSJ,'" + _BT + "' AS BT,DRIVERPHONE,STACKNAME,LXH,PACKAGE "//
            + "   FROM TRUCK_CARGO_LOGIN WHERE ID='" + _ID + "'";
            DataSet ds = ws.getDataSet_Serv(sql);



            report.LocalReport.ReportEmbeddedResource = "card.Reportp.rdlc";//加上报表的路径

            report.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", ds.Tables[0]));

            PrintStream(report.LocalReport);

            StringBuilder sbsql = new StringBuilder();
            sbsql.Append(" INSERT INTO TRUCK_CARGO_LOGIN_XPDY ");
            sbsql.Append(" (XPBH, LOGINTIME, TRUCKNO, REMARK, CARGONAME, YARD, PIECES, WEIGHT, OPERATOR, CARDTIME, CARDADD, SHIPNAME, BILL_NO, VOYAGE, COMMANDTIME, ZYJX, ZDR, DYRQ,PID,DRIVERPHONE,STACKNAME,PACKAGE,LXH) ");
            sbsql.Append("   SELECT  DECODE((SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%'),NULL, TO_CHAR(SYSDATE,'YYMM')||'000001',(SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%'))  AS BH ");
            sbsql.AppendFormat(" ,LOGINTIME, TRUCKNO, REMARK, CARGONAME, YARD, PIECES, WEIGHT, OPERATOR, CARDTIME, CARDADD, SHIPNAME, BILL_NO, VOYAGE, COMMANDTIME, ZYJX,'{0}', to_date('{1}' ,'yyyy-mm-dd hh24:mi:ss'),ID,DRIVERPHONE,STACKNAME,PACKAGE,LXH", Session.Operator_User, dtnow.ToString());
            sbsql.AppendFormat(" FROM TRUCK_CARGO_LOGIN WHERE ID = '{0}' ", _ID);

            ws.execute_UID_Serv(sbsql.ToString());


            StringBuilder sbsql1 = new StringBuilder();
            sbsql1.Append(" UPDATE TRUCK_CARGO_LOGIN ");
            sbsql1.Append(" SET DYBZ='1'");
            sbsql1.AppendFormat("  WHERE ID = '{0}' ", _ID);

            ws.execute_UID_Serv(sbsql1.ToString());
        }


        public void Run2(string _ID, string _BT)
        {
            DateTime dtnow = DateTime.Now;
            ReportViewer report = new ReportViewer();

            string sql = "  SELECT  XPBH AS BH " +
             " ,TRUCKNO AS CH,LOGINTIME AS DJSJ,COMMANDTIME AS ZLSJ,CARDTIME AS QRSJ,SHIPNAME||'/'||VOYAGE  AS CMHC "
             + ",BILL_NO  AS TDH,PIECES AS JS,CARGONAME AS HM,WEIGHT AS ZL,YARD AS DD,ZYJX AS JX, REMARK AS BZ "
             + " ,ZDR AS DZY,CARDADD AS TCC,DYRQ AS ZDSJ,'" + _BT + "' AS BT,DRIVERPHONE,STACKNAME,LXH,PACKAGE "//
           + "   FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH='" + _ID + "'";
            DataSet ds = ws.getDataSet_Serv(sql);




            report.LocalReport.ReportEmbeddedResource = "card.Reportp.rdlc";//加上报表的路径

            report.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", ds.Tables[0]));

            PrintStream(report.LocalReport);

            StringBuilder sbsql1 = new StringBuilder();
            sbsql1.Append(" UPDATE TRUCK_CARGO_LOGIN_XPDY ");
            sbsql1.Append(" SET DYCS=DYCS+1");
            sbsql1.AppendFormat("  WHERE XPBH = '{0}' ", _ID);

            ws.execute_UID_Serv(sbsql1.ToString());
        }

        /// <summary>
        /// 打印汽运单
        /// </summary>
        /// <param name="_ID"></param>
        /// <param name="_BT"></param>
        public void Run_QYD(string _ID)
        {
            ReportViewer report = new ReportViewer();

            string sql = "SELECT YARD, ZYJX, COMMANDTIME, CARDTIME, SYSDATE, DYBZ, TRUCKNO, REMARK FROM TRUCK_CARGO_LOGIN WHERE ID='" + _ID + "'";
            DataSet ds = ws.getDataSet_Serv(sql);

            string strDYBZ = ds.Tables[0].Rows[0]["DYBZ"].ToString();
            if (strDYBZ.Equals("1"))
            {
                if (MessageBox.Show("本操作将第二次打印该汽运单，是否继续？", "提示", MessageBoxButtons.OKCancel) != System.Windows.Forms.DialogResult.OK)
                    return;
            }

            report.LocalReport.ReportEmbeddedResource = "card.ReportQYD.rdlc";//加上报表的路径
            report.LocalReport.DataSources.Add(new ReportDataSource("DataSetQYD", ds.Tables[0]));
            PrintStream_QYD(report.LocalReport);

            //StringBuilder sbsql = new StringBuilder();
            //sbsql.Append(" INSERT INTO TRUCK_CARGO_LOGIN_XPDY ");
            //sbsql.Append(" (XPBH, LOGINTIME, TRUCKNO, REMARK, CARGONAME, YARD, PIECES, WEIGHT, OPERATOR, CARDTIME, CARDADD, SHIPNAME, BILL_NO, VOYAGE, COMMANDTIME, ZYJX, ZDR, DYRQ,PID,DRIVERPHONE,STACKNAME,PACKAGE,LXH) ");
            //sbsql.Append("   SELECT  DECODE((SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%'),NULL, TO_CHAR(SYSDATE,'YYMM')||'000001',(SELECT MAX( TO_NUMBER(XPBH))+1  FROM TRUCK_CARGO_LOGIN_XPDY WHERE XPBH LIKE TO_CHAR(SYSDATE,'YYMM')||'%'))  AS BH ");
            //sbsql.AppendFormat(" ,LOGINTIME, TRUCKNO, REMARK, CARGONAME, YARD, PIECES, WEIGHT, OPERATOR, CARDTIME, CARDADD, SHIPNAME, BILL_NO, VOYAGE, COMMANDTIME, ZYJX,'{0}', to_date('{1}' ,'yyyy-mm-dd hh24:mi:ss'),ID,DRIVERPHONE,STACKNAME,PACKAGE,LXH", Session.Operator_User, dtnow.ToString());
            //sbsql.AppendFormat(" FROM TRUCK_CARGO_LOGIN WHERE ID = '{0}' ", _ID);
            //ws.execute_UID_Serv(sbsql.ToString());

            StringBuilder sbsql1 = new StringBuilder();
            sbsql1.Append(" UPDATE TRUCK_CARGO_LOGIN ");
            sbsql1.Append(" SET DYBZ='1'");
            sbsql1.AppendFormat("  WHERE ID = '{0}' ", _ID);
            ws.execute_UID_Serv(sbsql1.ToString());
        }

        public void PrintStream_QYD(LocalReport rvDoc)
        {
            //获取LocalReport中的报表页面方向
            isLandSapces = rvDoc.GetDefaultPageSettings().IsLandscape;
            Export(rvDoc);
            try
            {
                PrintSetting_QYD();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            Dispose();
        }

        private void PrintSetting_QYD()
        {
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("错误:没有检测到打印数据流");
            //声明PrintDocument对象用于数据的打印
            PrintDocument printDoc = new PrintDocument();
            //获取配置文件的打印机名称
            Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            string strPrinter = config.AppSettings.Settings["QYDPrinter"].Value;
            bool bNeedSelectPriter = true;
            if (!string.IsNullOrEmpty(strPrinter))
            {
                foreach (string printname in PrinterSettings.InstalledPrinters)
                {
                    if (printname == strPrinter)
                    {
                        bNeedSelectPriter = false;
                        break;
                    }
                }
            }
            if (bNeedSelectPriter)
            {
                using (PrintSelectForm form = new PrintSelectForm(PrinterSettings.InstalledPrinters, "QYDPrinter"))
                {
                    form.ShowDialog();
                    if (form.DialogResult != System.Windows.Forms.DialogResult.OK)
                        return;
                    config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                    strPrinter = config.AppSettings.Settings["QYDPrinter"].Value;
                }
            }
            //printDoc.PrinterSettings.PrinterName = strPrinter;

            SetDefaultPrinter(strPrinter);//设置为默认打印机

            printDoc.PrintController = new System.Drawing.Printing.StandardPrintController();//指定打印机不显示页码 
            //判断指定的打印机是否可用
            if (!printDoc.PrinterSettings.IsValid)
            {
                MessageBox.Show("错误:找不到打印机");
            }
            else
            {
                //设置打印机方向遵从报表方向
                printDoc.DefaultPageSettings.Landscape = isLandSapces;
                //声明PrintDocument对象的PrintPage事件，具体的打印操作需要在这个事件中处理。
                printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
                m_currentPageIndex = 0;
                //设置打印机打印份数
                printDoc.PrinterSettings.Copies = 1;

                //自定义纸张大小
                System.Drawing.Printing.PageSettings df = new System.Drawing.Printing.PageSettings();
                df.PaperSize = new PaperSize("A4", 800, 500);
                printDoc.DefaultPageSettings = df;

                printDoc.Print();
            }
        }

        /// <summary>
        /// 用来记录当前打印到第几页了
        /// </summary>
        private int m_currentPageIndex;

        /// <summary>
        /// 声明一个Stream对象的列表用来保存报表的输出数据,LocalReport对象的Render方法会将报表按页输出为多个Stream对象。
        /// </summary>
        private IList<Stream> m_streams;

        private bool isLandSapces = false;

        /// <summary>
        /// 用来提供Stream对象的函数，用于LocalReport对象的Render方法的第三个参数。
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fileNameExtension"></param>
        /// <param name="encoding"></param>
        /// <param name="mimeType"></param>
        /// <param name="willSeek"></param>
        /// <returns></returns>
        private Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
        {
            //如果需要将报表输出的数据保存为文件，请使用FileStream对象。
            Stream stream = new MemoryStream();
            m_streams.Add(stream);
            return stream;
        }

        /// <summary>
        /// 为Report.rdlc创建本地报告加载数据,输出报告到.emf文件,并打印,同时释放资源
        /// </summary>
        /// <param name="rv">参数:ReportViewer.LocalReport</param>
        public void PrintStream(LocalReport rvDoc)
        {
            //获取LocalReport中的报表页面方向
            isLandSapces = rvDoc.GetDefaultPageSettings().IsLandscape;
            Export(rvDoc);
            PrintSetting();
            Dispose();
        }

        private void Export(LocalReport report)
        {
            string deviceInfo =
            @"<DeviceInfo>
                 <OutputFormat>EMF</OutputFormat>
             </DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            //将报表的内容按照deviceInfo指定的格式输出到CreateStream函数提供的Stream中。
            report.Render("Image", deviceInfo, CreateStream, out warnings);
            foreach (Stream stream in m_streams)
                stream.Position = 0;
        }

        private void PrintSetting()
        {
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("错误:没有检测到打印数据流");
            //声明PrintDocument对象用于数据的打印
            PrintDocument printDoc = new PrintDocument();
            //获取配置文件的清单打印机名称
            // System.Configuration.AppSettingsReader appSettings = new System.Configuration.AppSettingsReader();
            //  printDoc.PrinterSettings.PrinterName = appSettings.GetValue("QDPrint", Type.GetType("System.String")).ToString();

            //获取配置文件的打印机名称
            Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            string strPrinter = config.AppSettings.Settings["XPPrinter"].Value;
            bool bNeedSelectPriter = true;
            if (!string.IsNullOrEmpty(strPrinter))
            {
                foreach (string printname in PrinterSettings.InstalledPrinters)
                {
                    if (printname == strPrinter)
                    {
                        bNeedSelectPriter = false;
                        break;
                    }
                }
            }
            if (bNeedSelectPriter)
            {
                using (PrintSelectForm form = new PrintSelectForm(PrinterSettings.InstalledPrinters, "XPPrinter"))
                {
                    form.ShowDialog();
                    if (form.DialogResult != System.Windows.Forms.DialogResult.OK)
                        return;
                    config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                    strPrinter = config.AppSettings.Settings["XPPrinter"].Value;
                }
            }
            //printDoc.PrinterSettings.PrinterName = strPrinter;

            SetDefaultPrinter(strPrinter);//设置为默认打印机

            printDoc.PrintController = new System.Drawing.Printing.StandardPrintController();//指定打印机不显示页码 
            //判断指定的打印机是否可用
            if (!printDoc.PrinterSettings.IsValid)
            {
                throw new Exception("错误:找不到打印机");
            }
            else
            {
                //设置打印机方向遵从报表方向
                printDoc.DefaultPageSettings.Landscape = isLandSapces;
                //声明PrintDocument对象的PrintPage事件，具体的打印操作需要在这个事件中处理。
                printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
                m_currentPageIndex = 0;
                //设置打印机打印份数
                printDoc.PrinterSettings.Copies = 1;

                //自定义纸张大小
                System.Drawing.Printing.PageSettings df = new System.Drawing.Printing.PageSettings();
                df.PaperSize = new PaperSize("new size", 800, 500);
                printDoc.DefaultPageSettings = df;

                printDoc.Print();
            }
        }

        /// <summary>
        /// 处理程序PrintPageEvents
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ev"></param>
        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            //Metafile对象用来保存EMF或WMF格式的图形，
            //我们在前面将报表的内容输出为EMF图形格式的数据流。
            Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);
         
            //调整打印机区域的边距
            System.Drawing.Rectangle adjustedRect = new System.Drawing.Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                850);

            //绘制一个白色背景的报告
            //ev.Graphics.FillRectangle(Brushes.White, adjustedRect);

            //获取报告内容
            //这里的Graphics对象实际指向了打印机
            ev.Graphics.DrawImage(pageImage, adjustedRect);
            //ev.Graphics.DrawImage(pageImage, ev.PageBounds);

            // 准备下一个页,已确定操作尚未结束
            m_currentPageIndex++;

            //设置是否需要继续打印
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }

        public void Dispose()
        {
            if (m_streams != null)
            {
                foreach (Stream stream in m_streams)
                    stream.Close();
                m_streams = null;
            }
        }

        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern long SetDefaultPrinter(string pszPrinter);
    }
}
